using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;

using Peradigm.Framework.Configuration;
using Peradigm.Framework.Configuration.Messages;
using Peradigm.Framework.Domain.Exceptions;
using Peradigm.Framework.Persistence;

using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Tests.PersistenceTests
{
    /// <summary>
    /// General Set of Tests that need to be completed for each Broker
    /// </summary>
    public abstract class AbstractBrokerTests
    {
        #region Constants
        public const string 
            CONFIG_CXN_STRING           = "ConnectionString",
            ADMIN_CXN_STRING            = "TestAdminConnectionString";
        
        public const string 
            MSG_CONNECTION_FAILED       = "Database Connection Failed",
            MSG_WRONG_ATTRIBUTE_VALUE   = "Wrong value for <{0}>",
            MSG_WRONG_NUMBER_OF_RECORDS = "Expecting Different Number of records for <{0}>";
        #endregion

        #region SetUp and TearDown GenericBrokerTests
        [ClassInitialize()]
        public void Init()
        {
        }
        #endregion

        #region Test Methods
        [TestMethod()]
        public void ConfigTest()
        {
            string configCxn = ApplicationConfiguration.Settings[CONFIG_CXN_STRING];
            Assert.IsNotNull( configCxn, "WARNING: Connection String is not set or not found in the App.Config" );
        }

        [TestMethod()]
        public void DatabaseConnectionTest()
        {
            SqlConnection cxn = new SqlConnection();
            try
            {
                cxn.ConnectionString = this.ConnectionString;
                cxn.Open();
            }
            catch ( Exception )
            {
				throw;
            }
            finally
            {
                Assert.AreEqual( ConnectionState.Open, cxn.State, MSG_CONNECTION_FAILED );
                cxn.Close();
                cxn.Dispose();
            }
        }
        #endregion

        #region Support Methods
        virtual public string ConnectionString
        {
            get
            {          
                DefaultExecutionPolicy policy = new DefaultExecutionPolicy( ApplicationConfiguration.Settings[CONFIG_CXN_STRING] );
                return  policy.ConnectionString;
            }
        }
        
        virtual public string AdminConnectionString
        {
            get
            {          
                DefaultExecutionPolicy policy = new DefaultExecutionPolicy( ApplicationConfiguration.Settings[ADMIN_CXN_STRING] );      
                return  policy.ConnectionString;
            }
        }

        protected SqlConnection CurrentConnection
        {
            get
            {
                if( i_cxn == null )
                {
                    i_cxn = new SqlConnection( this.ConnectionString );
                    i_cxn.Open();
                }
                return i_cxn;
            }
        }

        protected SqlTransaction NewTransaction
        {
            get
            {
                if( i_txn == null )
                {
                    i_txn = this.CurrentConnection.BeginTransaction();
                }
                return i_txn;
            }
        }

        protected void Rollback()
        {
            if( i_txn != null )
            {
                i_txn.Rollback();
                i_txn.Dispose();
                i_txn = null;
            }
        }

        protected void Commit()
        {
            if( i_txn != null )
            {
                i_txn.Commit();
                i_txn.Dispose();
                i_txn = null;
            }
        }

        protected void CloseConnection()
        {
            if( i_cxn != null )
            {
                this.Rollback();
                i_cxn.Close();
                i_cxn.Dispose();
                i_cxn = null;
            }
        }
        #endregion

        #region Data Elements
        private SqlConnection i_cxn;
        private SqlTransaction i_txn;
        #endregion
        
        private class DefaultExecutionPolicy : SingleUsePolicy
        {
        #region Constants
        #endregion
        
        #region Methods
        #endregion
        
        #region Properties
        #endregion
        
        #region Private Methods
        #endregion
        
        #region Private Properties
        #endregion
        
        #region Construction and Finalization
        public DefaultExecutionPolicy( string cxnString ) : base( null, cxnString )
        {
        }
        #endregion
        
        #region Data Elements
        #endregion
        }
    }
}
